using Microsoft.EntityFrameworkCore;
using RAG.Application.Interfaces;
using RAG.Application.Dtos;
using RAG.Domain.Entities.App;
using RAG.Infrastructure.Data;
using Microsoft.Extensions.Configuration;
using RAG.Application.Commands; // This using statement is crucial for ApiResult
using RAG.Application.Services; // For PermissionCheckService

namespace RAG.Application.Services;

/// <summary>
/// 知识库服务实现
/// </summary>
public class AppKnowledgeBaseService : IAppKnowledgeBaseService
{
    private readonly RagDbContext _db;
    private readonly PermissionCheckService _permissionCheckService;

    public AppKnowledgeBaseService(RagDbContext db, PermissionCheckService permissionCheckService)
    {
        _db = db;
        _permissionCheckService = permissionCheckService;
    }

    /// <summary>
    /// 创建知识库
    /// </summary>
    public async Task<ApiResult> CreateKnowledgeBaseAsync(CreateKnowledgeBaseDto dto)
    {
        try
        {
            // 检查知识库名称是否已存在
            var existingKnowledgeBase = await _db.KnowledgeBases
                .FirstOrDefaultAsync(kb => kb.UserId == dto.UserId && kb.KnowledgeBaseName == dto.KnowledgeBaseName);

            if (existingKnowledgeBase != null)
            {
                return ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "知识库名称已存在");
            }

            var knowledgeBase = new KnowledgeBase
            {
                KnowledgeBaseId = Guid.NewGuid(),
                UserId = dto.UserId,
                KnowledgeBaseName = dto.KnowledgeBaseName,
                KnowledgeBaseDescription = dto.KnowledgeBaseDescription,
                IsPublic = dto.IsPublic,
                CreatedAt = DateTime.UtcNow,
                UpdatedAt = DateTime.UtcNow
            };

            _db.KnowledgeBases.Add(knowledgeBase);
            await _db.SaveChangesAsync();

            return ApiResult.Success("知识库创建成功", new { knowledgeBaseId = knowledgeBase.KnowledgeBaseId });
        }
        catch (Exception ex)
        {
            return ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"创建知识库失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 获取知识库列表
    /// </summary>
    public async Task<ApiResult> GetKnowledgeBasesAsync(Guid userId)
    {
        try
        {
            // 检查用户是否具有查看所有知识库的权限
            var canViewAll = await _permissionCheckService.CanViewAllAsync(userId, "knowledgebase");
            
            var query = _db.KnowledgeBases
                .Include(kb => kb.User) // 包含用户信息以便显示创建者
                .AsQueryable();

            // 如果具有查看所有知识库的权限，可以看到所有知识库；否则只能看到自己的和公开的
            if (!canViewAll)
            {
                query = query.Where(kb => (kb.UserId == userId || kb.IsPublic) && !kb.IsDeleted);
            }
            else
            {
                query = query.Where(kb => !kb.IsDeleted);
            }

            var knowledgeBases = await query
                .OrderBy(kb => kb.KnowledgeBaseName).ThenBy(kb => kb.KnowledgeBaseId) // 使用稳定的排序方式，避免启用禁用后上下跳动
                .Select(kb => new
                {
                    kb.KnowledgeBaseId,
                    kb.KnowledgeBaseName,
                    kb.KnowledgeBaseDescription,
                    kb.IsPublic,
                    kb.CreatedAt,
                    CreatorName = kb.User.Username, // 显示创建者用户名
                    DocumentCount = kb.Documents.Count(d => !d.IsDeleted),
                    IsOwner = kb.UserId == userId
                })
                .ToListAsync();

            return ApiResult.Success("获取知识库列表成功", knowledgeBases);
        }
        catch (Exception ex)
        {
            return ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"获取知识库列表失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 获取知识库详情
    /// </summary>
    public async Task<ApiResult> GetKnowledgeBaseAsync(Guid knowledgeBaseId)
    {
        try
        {
            var knowledgeBase = await _db.KnowledgeBases
                .Include(kb => kb.Documents)
                .FirstOrDefaultAsync(kb => kb.KnowledgeBaseId == knowledgeBaseId && !kb.IsDeleted);

            if (knowledgeBase == null)
            {
                return ApiResult.Failed((int)ApiStatusCode.NOT_FOUND, "知识库不存在");
            }

            var result = new
            {
                knowledgeBase.KnowledgeBaseId,
                knowledgeBase.KnowledgeBaseName,
                knowledgeBase.KnowledgeBaseDescription,
                knowledgeBase.IsPublic,
                knowledgeBase.CreatedAt,
                DocumentCount = knowledgeBase.Documents.Count(d => !d.IsDeleted),
                Documents = knowledgeBase.Documents.Where(d => !d.IsDeleted).Select(d => new
                {
                    d.DocumentId,
                    d.DocumentTitle,
                    d.DocumentFileName,
                    d.DocumentFileType,
                    d.DocumentStatus,
                    d.CreatedAt
                }).ToList()
            };

            return ApiResult.Success("获取知识库详情成功", result);
        }
        catch (Exception ex)
        {
            return ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"获取知识库详情失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 更新知识库
    /// </summary>
    public async Task<ApiResult> UpdateKnowledgeBaseAsync(UpdateKnowledgeBaseDto dto)
    {
        try
        {
            var knowledgeBase = await _db.KnowledgeBases
                .FirstOrDefaultAsync(kb => kb.KnowledgeBaseId == dto.KnowledgeBaseId && !kb.IsDeleted);

            if (knowledgeBase == null)
            {
                return ApiResult.Failed((int)ApiStatusCode.NOT_FOUND, "知识库不存在");
            }

            // 检查名称是否重复（排除当前知识库和已删除的知识库）
            var existingKnowledgeBase = await _db.KnowledgeBases
                .FirstOrDefaultAsync(kb => kb.UserId == knowledgeBase.UserId && 
                                         kb.KnowledgeBaseName == dto.KnowledgeBaseName && 
                                         kb.KnowledgeBaseId != dto.KnowledgeBaseId &&
                                         !kb.IsDeleted);

            if (existingKnowledgeBase != null)
            {
                return ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "知识库名称已存在");
            }

            knowledgeBase.KnowledgeBaseName = dto.KnowledgeBaseName;
            knowledgeBase.KnowledgeBaseDescription = dto.KnowledgeBaseDescription;
            knowledgeBase.IsPublic = dto.IsPublic;
            knowledgeBase.UpdatedAt = DateTime.UtcNow;

            await _db.SaveChangesAsync();

            return ApiResult.Success("知识库更新成功");
        }
        catch (Exception ex)
        {
            return ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"更新知识库失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 删除知识库（软删除）
    /// </summary>
    public async Task<ApiResult> DeleteKnowledgeBaseAsync(Guid knowledgeBaseId, Guid userId)
    {
        try
        {
            // 首先尝试查找用户自己的知识库
            var knowledgeBase = await _db.KnowledgeBases
                .Include(kb => kb.Documents)
                .FirstOrDefaultAsync(kb => kb.KnowledgeBaseId == knowledgeBaseId && kb.UserId == userId && !kb.IsDeleted);

            // 如果找不到自己的知识库，检查是否有删除所有知识库的权限
            if (knowledgeBase == null)
            {
                // 检查用户是否有删除所有知识库的权限
                var user = await _db.Users
                    .Include(u => u.Roles)
                    .ThenInclude(r => r.Permissions)
                    .FirstOrDefaultAsync(u => u.Id == userId);

                if (user == null)
                {
                    return ApiResult.Failed((int)ApiStatusCode.NOT_FOUND, "用户不存在");
                }

                var userPermissions = user.Roles
                    .SelectMany(r => r.Permissions)
                    .Select(p => p.PermissionCode)
                    .Distinct()
                    .ToList();

                // 如果有删除所有知识库的权限，则查找任何知识库
                if (userPermissions.Contains("knowledgebase.delete.all"))
                {
                    knowledgeBase = await _db.KnowledgeBases
                        .Include(kb => kb.Documents)
                        .FirstOrDefaultAsync(kb => kb.KnowledgeBaseId == knowledgeBaseId && !kb.IsDeleted);
                }
            }

            if (knowledgeBase == null)
            {
                return ApiResult.Failed((int)ApiStatusCode.NOT_FOUND, "知识库不存在或无权限删除");
            }

            // 软删除知识库下的所有文档
            foreach (var document in knowledgeBase.Documents)
            {
                document.IsDeleted = true;
                document.UpdatedAt = DateTime.UtcNow;
            }

            // 软删除知识库
            knowledgeBase.IsDeleted = true;
            knowledgeBase.UpdatedAt = DateTime.UtcNow;

            await _db.SaveChangesAsync();

            return ApiResult.Success("知识库删除成功");
        }
        catch (Exception ex)
        {
            return ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"删除知识库失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 添加文档到知识库
    /// </summary>
    public async Task<ApiResult> AddDocumentToKnowledgeBaseAsync(Guid knowledgeBaseId, Guid documentId)
    {
        try
        {
            var knowledgeBase = await _db.KnowledgeBases
                .FirstOrDefaultAsync(kb => kb.KnowledgeBaseId == knowledgeBaseId && !kb.IsDeleted);
            if (knowledgeBase == null)
            {
                return ApiResult.Failed((int)ApiStatusCode.NOT_FOUND, "知识库不存在");
            }

            var document = await _db.Documents
                .FirstOrDefaultAsync(d => d.DocumentId == documentId && !d.IsDeleted);
            if (document == null)
            {
                return ApiResult.Failed((int)ApiStatusCode.NOT_FOUND, "文档不存在");
            }

            // 检查文档是否已经在知识库中
            if (document.KnowledgeBaseId == knowledgeBaseId)
            {
                return ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "文档已在知识库中");
            }

            document.KnowledgeBaseId = knowledgeBaseId;
            document.UpdatedAt = DateTime.UtcNow;

            await _db.SaveChangesAsync();

            return ApiResult.Success("文档已添加到知识库");
        }
        catch (Exception ex)
        {
            return ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"添加文档到知识库失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 从知识库移除文档
    /// </summary>
    public async Task<ApiResult> RemoveDocumentFromKnowledgeBaseAsync(Guid knowledgeBaseId, Guid documentId)
    {
        try
        {
            var document = await _db.Documents
                .FirstOrDefaultAsync(d => d.DocumentId == documentId && d.KnowledgeBaseId == knowledgeBaseId && !d.IsDeleted);

            if (document == null)
            {
                return ApiResult.Failed((int)ApiStatusCode.NOT_FOUND, "文档不在知识库中");
            }

            // 由于文档必须属于一个知识库，我们选择软删除文档
            // 这样可以保持数据完整性，同时实现"移除"的效果
            document.IsDeleted = true;
            document.UpdatedAt = DateTime.UtcNow;

            // 同时软删除相关的文档块
            var documentChunks = await _db.DocumentChunks
                .Where(dc => dc.DocumentId == documentId)
                .ToListAsync();

            foreach (var chunk in documentChunks)
            {
                chunk.IsDeleted = true;
                chunk.UpdatedAt = DateTime.UtcNow;
            }

            await _db.SaveChangesAsync();

            return ApiResult.Success("文档已从知识库移除");
        }
        catch (Exception ex)
        {
            return ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"从知识库移除文档失败: {ex.Message}");
        }
    }
}
